function isArray(o){
    return Object.prototype.toString.call(o) === `[object Array]`
  }
  
  function isObject(o){
    return Object.prototype.toString.call(o) === `[object Object]`
  }
  
  class Observables{
      constructor(
        target,
        handler = {
          set(target, key, value, receiver){
            console.log('检测到了set的key为 -> ' + key);
            return Reflect.set(target, key, value, receiver);
          },
          get(target,key,receiver){
            console.warn('检测到了get的key为 -> ' + key);
            return Reflect.get(target,key,receiver)
          }
        }
      ){
        if( !isObject(target) && !isArray(target) ){
          throw new TypeError('target 不是数组或对象')
        }
  
        this._target = JSON.parse( JSON.stringify(target) );  // 避免引用修改  数组不考虑
        this._handler = handler;
  
        return new Proxy(this._observables(this._target), this._handler);
      }
      // 为每一项为Array或者Object类型数据变为代理
      _observables(target){
        // 遍历对象中的每一项
        for( const key in target ){
          // 如果对象为Object或者Array
          if( isObject(target[key]) || isArray(target[key]) ){
            // 递归遍历
            this._observables(target[key]);
            // 转为Proxy
            target[key] = new Proxy(target[key], this._handler);
          }
        }
        // 将转换好的target返回出去
        return target;
      }
    }